package com.xyzwps.paimon.furina.modules.sms.vcode

import com.xyzwps.paimon.furina.common.JSON
import com.xyzwps.paimon.furina.common.value.Phone
import com.xyzwps.paimon.furina.infra.EnchantedRBucket
import com.xyzwps.paimon.furina.infra.getEBucket
import org.redisson.api.RedissonClient
import org.redisson.codec.TypedJsonJacksonCodec
import org.springframework.stereotype.Repository
import java.time.Duration

@Repository
class RedissonVcodeContextRepository(private val redisson: RedissonClient) : VcodeContextRepository {
    private val contextTTLHours: Long = 24

    override fun getContext(phone: Phone, scene: VcodeScene): VcodeContext {
        val bucket = getBucket(phone, scene)
        return bucket.get() ?: VcodeContext(history = listOf())
    }

    override fun createContext(phone: Phone, scene: VcodeScene, ctx: VcodeContext) {
        val bucket = getBucket(phone, scene)
        bucket.setIfAbsent(ctx, Duration.ofHours(contextTTLHours))
    }

    override fun saveContext(phone: Phone, scene: VcodeScene, ctx: VcodeContext) {
        val bucket = getBucket(phone, scene)
        bucket.setIfExistsAndKeepTTL(ctx)
    }

    private val codec = TypedJsonJacksonCodec(VcodeContext::class.java, JSON.OM)

    private fun getBucket(phone: Phone, scene: VcodeScene): EnchantedRBucket<VcodeContext> {
        val contextKey = "furina:vcode-context-repository:scene:$scene:phone:${phone.value}"
        return redisson.getEBucket(contextKey, codec)
    }
}
